package com.ecar.common.datetime;

import com.ecar.common.util.StringUtil;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;


/** @noinspection unused, StringBufferMayBeStringBuilder */
public class TimeUtil {

	public static String FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static String TIME_FORMAT = "HH:mm:ss";
	public static String DATE_FORMAT = "yyyy-MM-dd";

	public static String compactTime(String orig) {
		if (orig == null) return null;

		String compact = orig.replace(":", "").replace(" ", "").replace("-", "");
		if (compact.length() > 14)
			compact = compact.substring(0, 14);

		return compact;
	}

	public static String compactToday() {
		String time = new SimpleDateFormat("yyyyMMdd").format(new Date());
		time += "000000";
		return time;
	}

	public static String compactCurrent() {
		return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
	}


	public static String getCurrentTime(boolean hasMillSecond) {
		GregorianCalendar calendar = new GregorianCalendar();
		StringBuffer strCurrentTime = new StringBuffer();
		strCurrentTime.append(TimeUtil.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2)).append(":");
		strCurrentTime.append(TimeUtil.addZero(calendar.get(Calendar.MINUTE), 2)).append(":");
		strCurrentTime.append(TimeUtil.addZero(calendar.get(Calendar.SECOND), 2));
		if (hasMillSecond)
			strCurrentTime.append(":").append(TimeUtil.addZero(calendar.get(Calendar.MILLISECOND), 3));
		return strCurrentTime.toString();
	}

	public static String addZero(int num, int len) {
		StringBuffer s = new StringBuffer();
		s.append(num);
		while (s.length() < len) { // 如果长度不足，则继续补0
			s.insert(0, "0"); // 在第1个位置处补0
		}
		return s.toString();
	}

	public static long time2Millis(String datetime) {
		try {
			SimpleDateFormat df = new SimpleDateFormat(FORMAT);
			Date date = df.parse(datetime);
			return date.getTime();
		} catch (ParseException e) {
			return -1;
		}
	}

	public static String time2Date(String dateTime) {
		SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
		Date d = null;
		try {
			d = df.parse(dateTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		if (d == null) return null;
		return df.format(d);
	}


	public static String currentDate() {
		SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
		return df.format(new Date());
	}

	public static String currentDateTime() {
		SimpleDateFormat df = new SimpleDateFormat(FORMAT);
		return df.format(new Date());
	}

	public static String regularTime(String time) {
		if (time != null && !time.contains("-"))
			return TimeUtil.compact2Normal(time);
		else
			return time;
	}

	public static String compact2Normal(String time) {
		if (time == null) return null;

		if (time.length() == 8) {
			try {
				SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
				Date date = df.parse(time);
				df = new SimpleDateFormat(DATE_FORMAT);
				return df.format(date);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			return null;
		}

		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			Date date = df.parse(time);
			df = new SimpleDateFormat(FORMAT);
			return df.format(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String date2Compact(String time) {
		if (time != null && time.length() <= 10)
			return time.replace("-", "");

		SimpleDateFormat df = new SimpleDateFormat(FORMAT);
		try {
			Date date = df.parse(time);
			df = new SimpleDateFormat("yyyyMMddHHmmss");
			return df.format(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 返回较晚的时间与较早的时间所差的天数
	 */
	public static int daysBetween(String pFormerStr, String pLatterStr) {
		GregorianCalendar pFormer = parse2Cal(pFormerStr);
		GregorianCalendar pLatter = parse2Cal(pLatterStr);

		return daysBetween(pFormer, pLatter);
	}


	/**
	 * 返回较晚的时间latter与较早former的时间所差的天数
	 * 如果早晚颠倒后传入有正负数之分
	 */
	public static int daysBetween(GregorianCalendar pFormer, GregorianCalendar pLatter) {
		GregorianCalendar vFormer = pFormer, vLatter = pLatter;
		boolean vPositive = true;
		if (pFormer.after(pLatter)) {
			vFormer = pLatter;
			vLatter = pFormer;
			vPositive = false;
		}
		vFormer.set(Calendar.MILLISECOND, 0);
		vFormer.set(Calendar.SECOND, 0);
		vFormer.set(Calendar.MINUTE, 0);
		vFormer.set(Calendar.HOUR_OF_DAY, 0);
		vLatter.set(Calendar.MILLISECOND, 0);
		vLatter.set(Calendar.SECOND, 0);
		vLatter.set(Calendar.MINUTE, 0);
		vLatter.set(Calendar.HOUR_OF_DAY, 0);

		int vCounter = 0;
		while (vFormer.before(vLatter)) {
			vFormer.add(Calendar.DATE, 1);
			vCounter++;
		}
		return vPositive ? vCounter : -vCounter;
	}

	/**
	 * 将字符串格式的日期转换为Calendar
	 * @param pDateStr
	 */
	public static GregorianCalendar parse2Cal(String pDateStr) {
		if (pDateStr == null) return null;
		String DATE_SEPARTOR = "-/ :";
		StringTokenizer sToken = new StringTokenizer(pDateStr, DATE_SEPARTOR);
		int year = Integer.parseInt(sToken.nextToken());
		int month = Integer.parseInt(sToken.nextToken()) - 1; // GregorianCalendar的月份是从0开始算
		int dayOfMonth = Integer.parseInt(sToken.nextToken());
		if (sToken.hasMoreTokens()) {
			int hourOfDay = Integer.parseInt(sToken.nextToken());
			int minute = Integer.parseInt(sToken.nextToken());
			int second = Integer.parseInt(sToken.nextToken());
			return new GregorianCalendar(year, month, dayOfMonth, hourOfDay,
				minute, second);
		}
		return new GregorianCalendar(year, month, dayOfMonth);
	}

	/**
	 * 计算出某天的前或后日期
	 * @param sDate 原始日期如：2011-3-6
	 * @param date  计算前(负数)n天或后(正数)n天，
	 *              如: 3(计算后3天,2011-3-9)；-3(计算前3天,2011-3-3)
	 * @return String
	 * @author Donny
	 */
	public static String addOrSubDate(String sDate, int date) {
		GregorianCalendar calendar = parseStr2Calendar(sDate);
		calendar.add(Calendar.DATE, date);
		return parseDate2Str(calendar.getTime(), DATE_FORMAT);
	}

	/**
	 * 将字符串格式的日期转换为Calender
	 * @param date String
	 * @return java.util.GregorianCalendar
	 */
	public static GregorianCalendar parseStr2Calendar(String date) {
		StringTokenizer sToken = new StringTokenizer(date, "-/");
		int iYear = Integer.parseInt(sToken.nextToken());
		// GregorianCalendar的月份是从0开始算起的
		int iMonth = Integer.parseInt(sToken.nextToken()) - 1;
		int iDay = Integer.parseInt(sToken.nextToken());
		return new GregorianCalendar(iYear, iMonth, iDay);
	}


	/**
	 * 日期转换成String，
	 * 输入日期，按照指定格式返回
	 * @param date
	 * @param pattern e.g: DATE_FORMAT_8 = "yyyyMMdd";
	 *                DATE_TIME_FORMAT_14 = "yyyyMMddHHmmss";
	 *                或者类似于二者的格式,e.g."yyyyMMddHH"，"yyyyMM"
	 * @return String
	 */
	public static String parseDate2Str(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}


	/**
	 * 给出当天二个时间(H:M:S)，返回二个时间的差值(单位：秒）
	 * @param "00:00:00"
	 * @return double类型
	 * @author tangsj
	 */
	public static double getSecondOfTwoTime(String time1, String time2) {
		DateFormat df = new SimpleDateFormat(TIME_FORMAT);
		try {
			long t1 = df.parse(time1).getTime();
			long t2 = df.parse(time2).getTime();
			long diff = (t1 < t2) ? t2 - t1 : t1 - t2;
			return diff / 1000;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}

	public static boolean isWeekend(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int day = cal.get(Calendar.DAY_OF_WEEK);
		return day == Calendar.SATURDAY || day == Calendar.SUNDAY;
	}

	public static GregorianCalendar getCalByDateTime(String time) {
		SimpleDateFormat df;
		if (time.length() > 10)
			df = new SimpleDateFormat(FORMAT);
		else
			df = new SimpleDateFormat(DATE_FORMAT);
		try {
			Date date = df.parse(time);
			GregorianCalendar cal = new GregorianCalendar();
			cal.setTime(date);
			return cal;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * sTime 格式 yyyy-MM-dd HH:mm:ss
	 */
	public static Date addOrSubHours(String sTime, int hours) {
		GregorianCalendar calendar = getCalByDateTime(sTime);
		if (calendar != null) {
			calendar.add(Calendar.HOUR, hours);
			return calendar.getTime();
		} else {
			return null;
		}
	}

	/**
	 * 格式化时间
	 * @param time
	 * @return
	 */
	public static String formatTime(String time) {
		if (time == null) return null;
		try {
			SimpleDateFormat df = new SimpleDateFormat(FORMAT);
			Date date = df.parse(time);
			return df.format(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 去掉时间，仅保留日期
	 * @param time
	 * @return
	 */
	public static Date timeToDate(Date time) {
		if (time == null) return parse(nextDate(0), DATE_FORMAT);
		return parse(formatTime(time, DATE_FORMAT), DATE_FORMAT);
	}

	/**
	 * 格式化时间文本
	 * @return
	 */
	public static String formatTime(Date time, String format) {
		if (time == null || format == null || format.equals("")) return null;
		try {
			SimpleDateFormat df = new SimpleDateFormat(format);
			return df.format(time);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 格式化时间文本
	 * @return
	 */
	public static String formatTime(Date time) {
		return formatTime(time, FORMAT);
	}

	/**
	 * 当前时间的文本
	 * @return
	 */
	public static String now() {
		return now(FORMAT);
	}

	/**
	 * 当前时间的文本
	 * @param formatter
	 * @return
	 */
	public static String now(String formatter) {
		if (StringUtil.isEmpty(formatter)) formatter = FORMAT;
		return formatTime(new Date(), formatter);
	}

	/**
	 * 今天的日期文本
	 * @return
	 */
	public static String today() {
		return today(DATE_FORMAT);
	}

	/**
	 * 今天的日期文本
	 * @param formatter
	 * @return
	 */
	public static String today(String formatter) {
		if (StringUtil.isEmpty(formatter)) formatter = DATE_FORMAT;
		return formatTime(new Date(), formatter);
	}

	/**
	 * 明天的日期文本
	 * @return
	 */
	public static String tomorrow() {
		return nextDate(1);
	}

	/**
	 * 明天的日期文本
	 * @param formatter
	 * @return
	 */
	public static String tomorrow(String formatter) {
		return nextDate(1, formatter);
	}

	/**
	 * 当前时间的指定天数之后的日期文本
	 * @param day
	 * @return
	 */
	public static String nextDate(int day) {
		return nextDate(day, DATE_FORMAT);
	}

	/**
	 * 当前时间的指定天数之后的日期文本
	 * @param day
	 * @param formatter
	 * @return
	 */
	public static String nextDate(int day, String formatter) {
		if (StringUtil.isEmpty(formatter)) formatter = DATE_FORMAT;
		Date date = next(new Date(), day);
		return formatTime(date, formatter);
	}

	/**
	 * 给定时间的指定天数之后的日期文本
	 * @param date
	 * @param day
	 * @return
	 */
	public static String nextDate(Date date, int day) {
		return nextDate(date, day, DATE_FORMAT);
	}

	/**
	 * 给定时间的指定天数之后的时日期文本
	 * @param date
	 * @param day
	 * @param formatter
	 * @return
	 */
	public static String nextDate(Date date, int day, String formatter) {
		if (StringUtil.isEmpty(formatter)) formatter = DATE_FORMAT;
		Date nextDate = next(date, day);
		return formatTime(nextDate, formatter);
	}

	/**
	 * 当前时候指定天数之后的时间
	 * @param day
	 * @return
	 */
	public static Date next(int day) {
		return next(new Date(), day);
	}

	/**
	 * 获取给定的日期的指定天数后的时间
	 * @param date
	 * @param day
	 * @return Date
	 */
	public static Date next(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, day);
		return calendar.getTime();
	}

	/**
	 * 获取指定时间hours小时后的时间
	 * @param date
	 * @param hours
	 * @return
	 */
	public static Date nextTime(Date date, int hours) {
		long milliseconds = hours * 3600000;
		long nextTime = date.getTime() + hours;
		return new Date(nextTime);
	}

	/**
	 * former是否早于latter
	 * @param former
	 * @param latter
	 * @return
	 */
	public static boolean before(Date former, Date latter) {
		Calendar cFormer = Calendar.getInstance();
		cFormer.setTime(former);
		Calendar cLatter = Calendar.getInstance();
		cLatter.setTime(latter);
		return cFormer.before(cLatter);
	}

	/**
	 * latter是否晚于former
	 * @param former
	 * @param latter
	 * @return
	 */
	public static boolean after(Date latter, Date former) {
		Calendar cFormer = Calendar.getInstance();
		cFormer.setTime(former);
		Calendar cLatter = Calendar.getInstance();
		cLatter.setTime(latter);
		return cLatter.after(cFormer);
	}

	/**
	 * 获取两个日期的相隔日数
	 */
	public static int days(Date d1, Date d2) {
		Calendar c1 = Calendar.getInstance();
		c1.setTime(d1);
		c1.set(Calendar.HOUR_OF_DAY, 0);
		c1.set(Calendar.MINUTE, 0);
		c1.set(Calendar.SECOND, 0);
		c1.set(Calendar.MILLISECOND, 0);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(d2);
		c2.set(Calendar.HOUR_OF_DAY, 0);
		c2.set(Calendar.MINUTE, 0);
		c2.set(Calendar.SECOND, 0);
		c2.set(Calendar.MILLISECOND, 0);

		return BigDecimal.valueOf(c1.getTime().getTime())
						 .subtract(BigDecimal.valueOf(c2.getTime().getTime()))
						 .divide(BigDecimal.valueOf(86400000), 2, BigDecimal.ROUND_DOWN)
						 .abs().intValue();
	}

	/**
	 * 解析时间字符串到Date对象，格式 yyyy-MM-dd HH:mm:ss
	 * @param time 时间字符串
	 * @return
	 */
	public static Date parse(String time) {
		return parse(time, FORMAT);
	}

	/**
	 * 解析时间字符串到Date对象，按照给出的格式，默认格式 yyyy-MM-dd HH:mm:ss
	 * @param time 时间字符串
	 * @param formatter 字符串格式
	 * @return
	 */
	public static Date parse(String time, String formatter) {
		try {
			if (StringUtil.isEmpty(formatter)) formatter = FORMAT;
			SimpleDateFormat sdf = new SimpleDateFormat(formatter);
			return sdf.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static boolean isToday(Date date) {
		String now = formatTime(date, DATE_FORMAT);
		String today = today(DATE_FORMAT);
		return now.equals(today);
	}

	public static Date timeOnly(Date date) {
		if (date == null) return parse(nextDate(0), TIME_FORMAT);
		return parse(formatTime(date, TIME_FORMAT), TIME_FORMAT);
	}

	public static Date joinDate(Date day, Date time) {
		String dayStr = formatTime(day, DATE_FORMAT);
		String timeStr = formatTime(time, TIME_FORMAT);
		return parse(dayStr + " " + timeStr);
	}

}
